Laplacian Smoothing and Mesh Dual¶
This notebook contains an exercise where you
- smooth a mesh by replacing each vertex with the average of its neighbors.
- compute the volume of a tetrahedral mesh
- compute the dual of a mesh by converting each vertex to a face such that the vertices of the new face correspond to the faces of the old mesh.
In [ ]:
from pygel3d import hmesh, jupyter_display as jd
from numpy import zeros
from numpy.linalg import det
jd.set_export_mode(True)
def mesh_stats(m):
print("# faces : ", m.no_allocated_faces(), " # vertices : ", m.no_allocated_vertices())
m = hmesh.load("bunnygtest.obj")
Problem 1: Insert code to complete the smoothing function¶
In [ ]:
def smooth(m, max_iter=1):
# max_iter: the amount smoothing iterations
pos = m.positions()
new_pos = zeros(pos.shape)
for _ in range(0, max_iter):
for v in m.vertices():
sum = 0
# visit neighbouring vertices and add their positions
for n in m.circulate_vertex(v):
sum += pos[n]
avg = sum / m.valency(v)
new_pos[v] = avg
# update the positions of the mesh to the average positions
pos[:] = new_pos
return m
Problem 2: Insert code to compute the volume of a triangle mesh¶
In [ ]:
import numpy as np
def calculate_volume(m):
pos = m.positions()
vol = 0
# Insert code ------>
for f in m.faces():
N = m.circulate_face(f, 'v')
vol += np.linalg.det([pos[n] for n in N]) / 6
# <------------------
return vol
print("Volume: ", calculate_volume(m))
Volume: 0.0007541261586712999
Problem 3: Insert code to complete the dual function¶
In [ ]:
def dual(m):
"""
The dual of a mesh is a new mesh constructed
from the original mesh where vertices become
faces and faces become vertices.
The dual of a 2-manifold polygonal mesh without boundary is com-
monly defined as another mesh with the same topology (genus)
but different connectivity (vertex-face incidence), in which faces
and vertices occupy complementary locations and the position of
each dual vertex is computed as the center of mass (barycenter or
centroid) of the vertices that support the corresponding face.
"""
m2 = hmesh.Manifold()
# Insert code ------>
for v in m.vertices():
dual_vertices = []
fs = m.circulate_vertex(v, 'f')
# dual_vertices consist of the barycenter (or centroid) of the vertices that support the corresponding face
dual_vertices.extend(m.centre(f) for f in fs)
m2.add_face(dual_vertices)
# <------------------
return m2
Show original mesh¶
If you don't see anything it is probably a problem with the path to data/bunnygtest.obj. The path should be relative to the current working directory: probably this is the directory that Jupyter Notebook shows when it starts.
In [ ]:
m = hmesh.load("bunnygtest.obj")
mesh_stats(m)
print("Volume: ", calculate_volume(m))
jd.display(m)
# faces : 6966 # vertices : 3485 Volume: 0.0007541261586712999
Show the smoothed mesh¶
In [ ]:
m_s = hmesh.Manifold(m)
smooth(m_s,50)
print("Volume: ", calculate_volume(m))
jd.display(m_s)
Volume: 0.0007541261586712999
Show the dual mesh¶
In [ ]:
mesh_stats(m)
m_d = dual(m)
mesh_stats(m_d)
jd.display(m_d)
# faces : 6966 # vertices : 3485 # faces : 3485 # vertices : 20898
When everything works, export this to an HTML file and submit that!